<template>
  <div class="box" ref="boxTag" v-cloak>
    <div class="message-div">
      <template
        v-if="historys.length > 0"
        v-for="(history, idx) in historys"
        :key="idx"
      >
        <!-- 用户输入 -->
        <div v-if="history.role == 'user'" class="message message_user">
          <img class="icon" src="@/assets/cat.jpg" alt="logo" />
          <div class="text" style="white-space: pre-wrap">
            {{ history.content }}
          </div>
        </div>
        <!-- GPT -->
        <div v-else class="message_system">
          <div class="message">
            <img
              class="icon"
              :class="get_gpt_css(idx)"
              src="@/assets/gpt.svg"
              alt="logo"
            />
            <template> </template>
            <div
              class="text"
              style="white-space: pre-wrap"
              v-html="markdown.render(history.content)"
            ></div>
          </div>
          <div class="row_flex">
            <div :class="get_copy_css(idx)">复制成功</div>
            <img
              class="icon show_icon click_trans"
              :class="last_button_hidden_css(idx)"
              @click="copyClick(history.content, idx)"
              src="@/assets/copy.svg"
              alt="logo"
            />
            <!-- <img
              class="icon show_icon click_trans"
              :class="last_button_hidden_css(idx)"
              @click="showClick(history.source, idx)"
              :src="require('@/assets/' + get_show_icon(idx))"
              alt="logo"
            /> -->
          </div>
        </div>
      </template>
      <template v-else>
        <img src="@/assets/gpt.svg" class="roate_logo" />
      </template>
      <div :class="hidden_window_css">{{ hidden_source_text }}</div>
    </div>
    <div class="input-div">
      <textarea
        class="input"
        ref="inputTag"
        :placeholder="input_placeholder"
        :disabled="input_disable_state"
        v-model="inputData"
        @input="inputChange"
        @keydown="textareaKeydown"
      />
      <div id="icon_div">
        <img
          class="input_icon icon_img"
          @click="message_send_click"
          :src="require('@/assets/' + input_tag_icon)"
          alt="send"
        />
        <!-- <img class="input_icon icon_img" @click="" src="../assets/voice.svg" alt="voice" title="语音"/>
                <img class="input_icon icon_img" @click="" src="../assets/file.svg" alt="upload" title="上传文件" /> -->
      </div>
    </div>
  </div>
</template>
<script setup>
import {
  ref,
  nextTick,
  onMounted,
  reactive,
  computed,
} from "vue";
import MarkdownIt from "markdown-it";
import hljs from "highlight.js";
import "highlight.js/styles/vs2015.css";

const markdown = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    // 得到经过highlight.js之后的html代码
    const code = hljs.highlight(str, {
      language: lang || "javascript",
      ignoreIllegals: true,
    }).value;
    return code;
  },
});

let props = defineProps(["historys"]);
let emits = defineEmits([
  "sendClick",
  "voiceClick",
  "uploadClick",
  "slideToBottom",
  "chat_start",
  "chat_done",
  "stopGenerate",
]);
let inputTag = ref(null);
let boxTag = ref(null);
let inputData = defineModel({
  typing: String,
  default: "",
});
// 要暴露的函数
defineExpose({ slideToBottom, chat_start, chat_done });

/* ---------------------------------- 滑动到底部 --------------------------------- */
function slideToBottom() {
  nextTick(() => {
    boxTag.value.scrollTop = boxTag.value.scrollHeight;
  });
}
/* --------------------------------- 对话开始与结束 -------------------------------- */
let is_chating = ref(false);
function chat_start() {
  is_chating.value = true;
}
function chat_done() {
  is_chating.value = false;
  slideToBottom();
  nextTick(() => {
    inputTag.value.focus();
  });
}
/* -------------------------------- 输入框的禁用与启用 ------------------------------- */
const input_placeholder = computed(() => {
  return is_chating.value ? "AI is thinking ..." : "type something ...";
});
const input_disable_state = computed(() => {
  return is_chating.value;
});
/* ------------------------------ 对话图标和停止图标的更换 ------------------------------ */
const input_tag_icon = computed(() => {
  return is_chating.value ? "stop.svg" : "send.svg";
});
/* -------------------------------- gpt图标旋转控制 ------------------------------- */
function get_gpt_css(idx) {
  return reactive({
    roate: idx == props.historys.length - 1 && is_chating.value,
  });
}
/* ------------------------------ 复制按钮和显示按钮是否展示 ----------------------------- */
function last_button_hidden_css(idx) {
  // 默认是-1，和所有的都不相等，false即展示
  return reactive({
    display_none: props.historys.length - 1 == idx && is_chating,
  });
}

/* ------------------------------ 页面加载完毕后滑动到底部 ------------------------------ */
onMounted(() => {
  slideToBottom();
  inputTag.value.focus();
});
/* ----------------------------- textarea高度自动调整 ----------------------------- */
function inputChange() {
  nextTick(() => {
    inputTag.value.style.height = "30px";
    inputTag.value.style.height = `${inputTag.value.scrollHeight}px`;
    slideToBottom();
  });
  //  inputTag.value.style.height = `${rows*30}px`
}

/* ---------------------------- 点击发送按钮，触发父组件回调函数 ---------------------------- */
function message_send_click() {
  if (is_chating.value) {
    // emits("stopGenerate");
    return;
  }
  let trim_str = String(inputData.value).trim();
  if (trim_str) {
    // if (inputData.value) {
    emits("sendClick", trim_str);
    inputData.value = "";
    inputChange();
  }
}

/* -------------------- 修改默认行为，enter发送，shift + enter 执行换行 ------------------- */
function textareaKeydown(e) {
  if (e.shiftKey && e.key === "Enter") {
    inputData.value = inputData.value + "\n";
  } else if (e.key === "Enter") {
    e.preventDefault();
    message_send_click();
  }
}
/* --------------------------------- 复制按钮被点击 -------------------------------- */
let copy_active_idx = ref(-1);
function get_copy_css(idx) {
  return reactive({
    copy_success: idx == copy_active_idx.value,
    display_none: idx != copy_active_idx.value,
    copy_default: true,
  });
}
function copyClick(data, idx) {
  navigator.clipboard.writeText(data).then(() => {
    copy_active_idx.value = idx;
    console.log(copy_active_idx);
    setTimeout(() => {
      copy_active_idx.value = -1;
    }, 1000);
  });
}
/* -------------------------------- 显示按钮点击事件 -------------------------------- */
let hidden_source_text = ref("");
let hidden_source_text_idx = ref(-1);

function get_show_icon(idx) {
  return idx == hidden_source_text_idx.value ? "show_red.svg" : "show.svg";
}
let hidden_window_css = reactive({
  display_none: true,
  hidden_window_default: true,
  hidden_window_open: false,
});

function showClick(data, idx) {
  if (hidden_window_css.display_none) {
    // 从无到有
    hidden_window_css.display_none = !hidden_window_css.display_none;
    hidden_window_css.hidden_window_open =
      !hidden_window_css.hidden_window_open;
    hidden_source_text_idx.value = idx;
  } else {
    if (hidden_source_text_idx.value == idx) {
      // 从有到无
      hidden_source_text_idx.value = -1;
      hidden_window_css.display_none = !hidden_window_css.display_none;
      hidden_window_css.hidden_window_open =
        !hidden_window_css.hidden_window_open;
    } else {
      // 从有到有
      hidden_source_text_idx.value = idx;
    }
    // 从有到有
  }
  hidden_source_text.value = data;
}

/*********---gpt图标旋转控制---*********/
let rotate_speed = reactive([1500, 1580, 1650, 1700]);
for (let i = 0; i < rotate_speed.length; i++) {
  rotate_speed[i] = "rotate(" + rotate_speed[i] * 0.7 + "deg)";
}
</script>

<style scoped>
.box {
  height: 100%;
  background-color: #353640;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  font-family: "Times New Roman", Times, serif;
  font-size: 1.1em;
  line-height: 1.2;
  letter-spacing: 1px;
  overflow-y: auto;
}

.message-div {
  width: 100%;
  display: flex;
  flex-direction: column;
  user-select: none;
  justify-content: flex-start;
  align-items: flex-start;
}

/* 头像 */
.message_system {
  width: 100%;
  background-color: #444654;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
}

.message_user {
  background-color: #343541;
}

.message {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: flex-start;
  padding: 2%;
}

.icon {
  width: 30px;
  height: 30px;
  margin-right: 14px;
}

.text {
  font-size: normal;
  color: #ffffff;
  word-break: break-all;
  margin-top: 7px;
  width: 100%;
  /* margin: 20%; */
}

.input-div {
  width: 60%;
  background-color: #40414f;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: flex-end;
  margin-top: 2%;
  margin-bottom: 2%;
  padding-left: 1%;
  padding-bottom: 10px;
  padding-top: 18px;
  border-radius: 5px;
}

.input {
  width: 90%;
  height: 30px;
  background-color: #40414f;
  color: white;
  border: none;
  resize: none;
  border-right: none;
  font-size: 18px;
  padding: 0px;
  padding-left: 2%;
  padding-right: 2%;
  /* padding-top: 1.5%; */
}

.input:focus {
  outline: none;
  /* border: 1px solid #40414f; */
}

#icon_div {
  width: 10%;
  background-color: #40414f;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
  padding-right: 2%;
  padding-bottom: 2px;
}

.input_icon {
  background-color: #40414f;
  transform: scale(1);
  width: 30px;
  height: 30px;
  background-repeat: no-repeat;
}

.icon_img:hover {
  background-color: #454646;
  cursor: pointer;
}

.icon_img:active {
  transform: scale(0.8);
}

.show_icon {
  margin-bottom: 10px;
  margin-right: 20px;
}

.row_flex {
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-items: center;
}

.click_trans {
  transform: scale(1);
}

.click_trans:hover {
  cursor: pointer;
}

.click_trans:active {
  transform: scale(0.9);
}

/*********---gpt图标旋转控制---*********/
.roate {
  animation: roates 1s linear infinite;
}

@keyframes roates {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/*********---复制成功控制---*********/

.display_none {
  display: none;
}

.copy_default {
  opacity: 0;
  color: #0dbc79;
  position: relative;
  bottom: 3px;
  right: 7px;
}

.copy_success {
  animation: copy_success 1s linear;
  animation-fill-mode: forwards;
}

@keyframes copy_success {
  0% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

/*********---显示按钮事件---*********/
.hidden_window_default {
  color: #ffffff;
  position: absolute;
  right: 20%;
  top: 8%;
  /* transform: translate(-50%, 150%); */
  background-color: #252526;
  font-family: "Times New Roman", Times, serif;
  letter-spacing: 1px;
  white-space: pre-wrap;
  /* 保留换行符并在必要时自动换行 */
  padding: 10px;
  overflow-y: auto;
  border: 3px solid #3c3c3c;
}

.hidden_window_open {
  animation: open_window 0s linear;
  animation-fill-mode: forwards;
}

@keyframes open_window {
  0% {
    width: 0;
    height: 0;
  }

  100% {
    width: 700px;
    height: 550px;
  }
}

.roate_logo {
  position: absolute;
  width: 100px;
  height: 100px;
  left: 53%;
  top: 10%;
  user-select: none;
  /* 旋转貌似并不好看 */
  /* animation: roates2 2s linear;
    animation-fill-mode: forwards; */
}

@keyframes roates2 {
  0% {
    transform: rotate(0deg);
  }

  70% {
    transform: v-bind("rotate_speed[0]");
  }

  80% {
    transform: v-bind("rotate_speed[1]");
  }

  90% {
    transform: v-bind("rotate_speed[2]");
  }

  100% {
    transform: v-bind("rotate_speed[3]");
  }
}
:deep(pre) {
  display: block;
  background-color: #2c2c36;
  width: 800px;
  padding: 10px;
  overflow-x: auto;
  border-radius: 8px;
}
.text :deep(p) {
  margin: 0;
}
/* .text :deep(span){
  margin-top: 10px;
} */
</style>
